package com.adcc.ags.cgw.service;

import com.adcc.ags.cgw.entity.msg.CGWMsg;
import com.adcc.ags.cgw.entity.msg.MsgType;
import com.adcc.ags.cgw.entity.mq.MQState;
import com.adcc.ags.cgw.entity.user.User;
import com.adcc.ags.cgw.managed.proxy.MsgProxy;
import com.adcc.ags.cgw.managed.uplink.UplinkForward;
import com.adcc.ags.cgw.utils.Constant;
import com.adcc.utility.log.Log;
import com.adcc.utility.mq.entity.Message;
import com.adcc.utility.mq.transfer.MQTransfer;
import com.google.common.base.Optional;
import com.google.common.collect.Maps;

import java.util.HashMap;
import java.util.Map;

/**
 * 接收报文服务
 */
public class MsgReceiverServiceImpl extends MsgReceiverService {

    @Override
    protected Optional<CGWMsg> receiveMsg(MQTransfer transfer, User user) {

        Optional<CGWMsg> result = Optional.absent();
        try {

            if (UplinkForward.getInstance().getMQInfo().getState() == MQState.CONNECTED) {
                // 上行收报
                Message message = null;
                try {
                    message = transfer.receiveQueue(user.getSendQueue());
                } catch (Exception ex) {
                    Log.error(MsgReceiverService.class.getName(), "receive message from queue:" + user.getSendQueue() + " error", ex);
                    UplinkForward.getInstance().getMQInfo().setState(MQState.CONNECTING);
                }

                // 上行报处理
                if (message != null) {
                    String msgType = (String) message.getHead().get(Constant.STRING_MSG_TYPE);
                    String msgSender = (String) message.getHead().get(Constant.STRING_MSG_SENDER);

                    // 如果上行报文头标识不是Uplink或Ground，则不处理接收的上行报文
                    if (MsgType.Uplink.toString().equals(msgType) || MsgType.Ground.toString().equals(msgType)) {
                        Log.info(MsgReceiverService.class.getName(), "receive message from user:" + msgSender + " type:" + msgType + "\r\n" + message);
                        CGWMsg cgwMsg = new CGWMsg(message, MsgType.valueOf(msgType), msgSender);
                        result = Optional.of(cgwMsg);
                    } else {
                        Log.error(MsgReceiverService.class.getName(), "receive invalid message from user:" + msgSender + " type:" + msgType + "\r\n" + message);
                    }
                }
            } else {
                // 尝试连接MQ
                if (!UplinkForward.getInstance().connectMQ()) {
                    UplinkForward.getInstance().getMQInfo().setState(MQState.CONNECTING);
                }
            }
        } catch (Exception ex) {
            Log.error(MsgReceiverService.class.getName(), "receiveMsg() error", ex);
        }
        return result;
    }

    @Override
    public void onReceive(Object message) {
        super.onReceive(message);

        try {
            if (message instanceof Map) {

                Map<String,Object> map = (HashMap<String,Object>)message;
                if(map.containsKey(Constant.STRING_RECEIVER_ACTOR_KEY1) && map.containsKey(Constant.STRING_RECEIVER_ACTOR_KEY2)){

                    // 获取实体
                    MQTransfer transfer = (MQTransfer)map.get(Constant.STRING_RECEIVER_ACTOR_KEY1);
                    User user = (User)map.get(Constant.STRING_RECEIVER_ACTOR_KEY2);

                    // 上行收报处理
                    Optional<CGWMsg> optional = receiveMsg(transfer,user);
                    if (optional.isPresent()) {
                        Map<String, Object> verifyMap = Maps.newHashMapWithExpectedSize(2);
                        verifyMap.put(Constant.STRING_VERIFY_ACTOR_KEY1, optional.get());
                        verifyMap.put(Constant.STRING_VERIFY_ACTOR_KEY2, user);
                        MsgProxy.getInstance().getMsgVerifyActor().tell(verifyMap, this.getSelf());

                        // 消息入库处理
                        saveMsg(optional.get());
                    }
                } else {
                    unhandled(message);
                }
            } else {
                unhandled(message);
            }
        } catch (Exception ex) {
            Log.error(MsgReceiverService.class.getName(), "onReceive() error", ex);
        }
    }
}
